import cv2
import numpy as np


# 显示图片
def cv_show(image_name, image):
    cv2.namedWindow(image_name, cv2.WINDOW_NORMAL)
    cv2.imshow(image_name, image)
    cv2.waitKey(0)


# 提取原图中的竖线坐标，并返回排序之后的横坐标列表
def get_column_line(original_image):
    # 先对图片进行二值化操作
    binary_image = cv2.threshold(original_image, 128, 255, cv2.THRESH_BINARY)[1]
    height, width = binary_image.shape[:2:]
    binary = ~binary_image.copy()

    # 识别竖线
    scale = 40
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, height // scale))
    # 腐蚀
    eroded = cv2.erode(binary, kernel, iterations=1)
    # 膨胀
    dilated_row = cv2.dilate(eroded, kernel, iterations=1)

    # 使用Hough线变换来检测线条
    lines = cv2.HoughLinesP(dilated_row, 1, np.pi / 180, 20, minLineLength=10, maxLineGap=500)

    # 将线条存储到列表中
    col = []
    for line in lines:
        x1, y1, x2, y2 = line[0]
        col.append(x1)

    # 在原图上绘制检测到的线条
    #     cv2.line(test, (x1, y1), (x2, y2), (255, 0, 255), 1)
    # cv_show("original_image", original_image.copy())

    # 将x值归类排序，存储竖线的x值
    col_list = sort_and_reduce_line(col)

    return col_list


# 对竖线排序和归类
def sort_and_reduce_line(list):
    # 创建一个新的数组用来存放结果
    new_list = []
    # 先对数组的值排序
    list.sort()

    # s和c分别表示总和 和 数量
    s = list[0]
    c = 1
    # 跳过第一个元素
    for i in range(1, len(list)):
        # 如果相邻的两个元素差值很小，继续往后遍历
        if list[i] - list[i - 1] < 20:
            s += list[i]
            c += 1
        # 直到差值较大时，存储此时的平均值
        else:
            new_list.append(s // c)
            s = list[i]
            c = 1
    # 将最后一组存储到列表
    new_list.append(s // c)
    return new_list
